home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.09 Sep 93 / FrameAnim App ƒ / Files.c < prev    next >
Encoding:
Text File  |  1994-11-06  |  8.6 KB  |  302 lines  |  [TEXT/KAHL]

  1. // ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  2. // • Program:    FrameAnim
  3. // • File:        Files.c
  4. // •
  5. // • Copyright © 1993 by Scott B. Steinman, O.D., Ph.D. All Rights Reserved.
  6. // ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  7. // • NOTES:
  8. // •    Animation files are saved in a PICS file format that includes:
  9. // •    (a) One 'INFO' resource for playback information.
  10. // •    (b) One 'PICT' (PICT2) resource for each stored image.
  11. // ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  12.  
  13. #include "FrameAnim.h"
  14.  
  15. #include <Files.h>
  16. #include <StandardFile.h>
  17. #include <PictUtil.h>
  18.  
  19. // • ------------------ External Globals ---------------------------------- 
  20.  
  21. extern GWorldPtr        gFrames[];        // • From Main.c file
  22. extern PaletteHandle    gPalette;        // • From Main.c file
  23. extern CTabHandle        gCTable;        // • From Main.c file
  24. extern Handle            gMenuBar;        // • From Main.c file
  25. extern Settings            gSettings;        // • From Main.c file
  26. extern Flags            gFlags;            // • From Main.c file
  27. extern Rect                gBounds;         // • From Animation.c file
  28.  
  29. // • ------------------ Internal Globals ---------------------------------- 
  30.  
  31. PicHandle                gFramePICTs[ kMaxFrames ];    // • Frame Pictures
  32.  
  33. // •------------------- Static Variables ----------------------------------
  34.  
  35. static PICSInfoHandle    sPicInfo;        // • Animation parameters 
  36.  
  37. // • ------------------ Static Functions ---------------------------------- 
  38.  
  39. static void        DrawPICTToGWorld( const short );
  40. static void        NewColorsFromPICT( void );
  41. static void        ReadFilm( const StandardFileReply * );
  42. static void        WriteFilm( const StandardFileReply * );
  43.  
  44. // • ------------------ Save Frame Images in File ------------------------- 
  45.  
  46. void
  47. SaveFilm( void )
  48. // •
  49. // • Save an animation sequence to animation file on disk.
  50. {
  51.     StandardFileReply    theReply;
  52.     Str255                thePrompt, theDefaultName;
  53.  
  54.     strcpy( (char *) thePrompt, (char *) "\pSave Animation File as..." );    
  55.     strcpy( (char *) theDefaultName, (char *) "\p" );                        
  56.  
  57.     StandardPutFile( &thePrompt, &theDefaultName, &theReply );        
  58.  
  59.     if (theReply.sfGood) {
  60.     
  61.         FSpCreateResFile( &theReply.sfFile, 'FRMA', 'PICS', theReply.sfScript );
  62.         WriteFilm( &theReply );
  63.     }
  64. }
  65.  
  66. // • ------------------ Write the Frames to File -------------------------- 
  67.  
  68. static void
  69. WriteFilm( const StandardFileReply *theReply )
  70. // •
  71. // • Writes entire animation sequence to animation file on disk.
  72. {
  73.     OSErr        resultCode;
  74.     short        resFile, i;
  75.     Str255        frameText;
  76.  
  77.     // • Transfer animation information to PicsInfo record
  78.  
  79.     sPicInfo = (PICSInfoHandle) NewHandle( sizeof( PICSInfoRec ) );
  80.     if (sPicInfo == NullHandle)
  81.         ErrorHandler( kNoMemoryMsg, (char *) NilString, (char *) NilString, 
  82.          (char *) NilString );
  83.  
  84.     HLock( (Handle) sPicInfo );
  85.     (**sPicInfo).speed = RoundUp( kRefreshRate / gSettings.frameDelay );
  86.     (**sPicInfo).depth = kDepth;
  87.     (**sPicInfo).version = 0;
  88.     (**sPicInfo).creator = 'FRMA';
  89.     (**sPicInfo).largest = 0;            // • Not used.
  90.     (**sPicInfo).bwColor = 1; 
  91.     HUnlock( (Handle) sPicInfo );
  92.  
  93.     // • Write the animation info and frames to resource fork of file 
  94.  
  95.     resFile = FSpOpenResFile( &theReply->sfFile, fsWrPerm );
  96.     AddResource( sPicInfo, 'INFO', kPICSInfoID, "\pAnimation Parameters" );                                                    
  97.  
  98.     for (i = 0; i < gSettings.numFrames; i++) {
  99.         PtoCstr( (char *) frameText );
  100.         sprintf( (char *) frameText, "Animation Frame %d of %ld", i + 1,
  101.          gSettings.numFrames );
  102.         CtoPstr( (char *) frameText );
  103.         
  104.         AddResource( gFramePICTs[ i ], 'PICT', kFirstPictID + i, frameText );
  105.         UpdateResFile( resFile );        // • Force write of resource to file.
  106.     }
  107.         
  108.     CloseResFile( resFile );
  109.     
  110.     // • Null handles to resources that have been freed by CloseResFile 
  111.     
  112.     sPicInfo = NullHandle;
  113.     for (i = 0; i < gSettings.numFrames; i++) 
  114.         gFramePICTs[ i ] = NullHandle;
  115.     
  116.     DisableItem( GetMHandle( kFileID ), kSaveFilmItem );                    
  117. }
  118.  
  119. // • ------------------ Open Animation Sequence File ---------------------- 
  120.  
  121. void
  122. OpenFilm( void )
  123. // •
  124. // • Retrieve entire animation sequence from animation file on disk.
  125. {
  126.     SFTypeList            typeList;
  127.     StandardFileReply    theReply;
  128.     short                numTypes;    
  129.     
  130.      numTypes = 1;                                // • Only one type of file 
  131.     typeList[ 0 ] = 'PICS';                        // • Only Animation files 
  132.     
  133.     StandardGetFile( NullPointer, numTypes, &typeList, &theReply );
  134.  
  135.     if (theReply.sfGood)
  136.         ReadFilm( &theReply );
  137.     else
  138.         gFlags.cancel = true;
  139. }
  140.  
  141. // • ------------------ Read the Frames from File ------------------------- 
  142.  
  143. static void
  144. ReadFilm( const StandardFileReply *theReply )
  145. // •
  146. // • This does the opposite of WriteFilm.
  147. {
  148.     PictInfo    pictInfo;
  149.     OSErr        err;
  150.     short        resFile, i;    
  151.  
  152.     // • Remove any previously-allocated color records 
  153.  
  154.     if (gCTable != NullHandle) {
  155.         DisposCTable( gCTable );
  156.         gCTable = NullHandle;
  157.     }
  158.     if (gPalette != NullHandle) {
  159.         DisposePalette( gPalette );
  160.         gPalette = NullHandle;
  161.     }
  162.  
  163.     // • Read the animation information resource. 
  164.     
  165.     resFile = FSpOpenResFile( &theReply->sfFile, fsRdPerm );
  166.     
  167.     sPicInfo = (PICSInfoHandle) Get1Resource( 'INFO', kPICSInfoID );
  168.     
  169.     // • Pull out frame delay from PICS resource (other fields ignored here) 
  170.  
  171.     HLock( (Handle) sPicInfo );
  172.     gSettings.frameDelay = RoundUp( kRefreshRate / (**sPicInfo).speed );
  173.     HUnlock( (Handle) sPicInfo );
  174.  
  175.     // • Prepare new frame GWorlds.
  176.  
  177.     PrepareFilm();        // • Allocate frame storage & update palettes.     
  178.  
  179.     // • Find the number of frame image PICT resources. 
  180.     
  181.     gSettings.numFrames = Count1Resources( 'PICT' );
  182.     
  183.     // • Copy contents of first PICT resource to first PICT record.
  184.     
  185.     DisposeFramePICTs();         
  186.     gFramePICTs[ 0 ] = GetPicture( kFirstPictID );
  187.     DetachResource( gFramePICTs[ 0 ] );                                                    
  188.     
  189.     // • Get frame size info from first PICT.
  190.  
  191.     err = GetPictInfo( gFramePICTs[ 0 ], &pictInfo, 
  192.      returnColorTable+suppressBlackAndWhite, kNumColors, systemMethod, 0 );
  193.     gSettings.frameSize = pictInfo.sourceRect.right - pictInfo.sourceRect.left;    
  194.  
  195.     // • Get color info from PICT to reset color table and palette.
  196.  
  197.     HLock( (Handle) pictInfo.theColorTable );
  198.     gSettings.bkgndGray =  (**pictInfo.theColorTable).ctTable[ 0 ].rgb.red / 256;
  199.     gSettings.targetGray = (**pictInfo.theColorTable).ctTable[ 1 ].rgb.red / 256;
  200.     HUnlock( (Handle) pictInfo.theColorTable );
  201.     DisposCTable( pictInfo.theColorTable );
  202.     
  203.     NewColorsFromPICT();    // • Create and initialize color table and palette.
  204.     
  205.     UpdateWindowColors();
  206.     ResetForeAndBackColors();
  207.     ResetWindBkgnd();
  208.     
  209.     DrawPICTToGWorld( 0 );    // • Transfer the frame image from PICT to GWorld.
  210.  
  211.     for (i = 1; i < gSettings.numFrames; i++) { 
  212.         gFramePICTs[ i ] = GetPicture( kFirstPictID + i );
  213.         DetachResource( gFramePICTs[ i ] );                                                    
  214.         DrawPICTToGWorld( i );            
  215.     }    
  216.     ResetForeAndBackColors();
  217.                 
  218.     CloseResFile( resFile );
  219.     
  220.     // • Null out resource handles freed by CloseResFile
  221.     
  222.     sPicInfo = NullHandle;
  223.     for (i = 0; i < gSettings.numFrames; i++)
  224.          gFramePICTs[ i ] = NullHandle;
  225.  
  226.     SysBeep( 1 );
  227. }
  228.  
  229. // • ------------------ Create and Initialize New CTable From PICT -------- 
  230.  
  231. static void
  232. NewColorsFromPICT( void)
  233. // •
  234. // • Create and initialize color table and palette
  235. // • using background and target colors found in animation file.
  236. {
  237.     RGBColor    c;
  238.     short        i;
  239.     
  240.     // • Create new CTable and palette.
  241.     
  242.     gCTable = GetCTable( kGrayCTableID );
  243.     DetachResource( gCTable ); 
  244.     (*gCTable)->ctFlags |= 0x4000;        // • Speeds up later CopyBits calls
  245.     gPalette = NewPalette( kNumColors, gCTable, pmTolerant+pmExplicit, 0 );
  246.  
  247.     // • Initialize palette entries.
  248.  
  249.     c.red = c.green = c.blue = 0;
  250.     for (i = 0; i < kNumColors; i++) {
  251.         SetEntryColor( gPalette, i, &c );
  252.         SetEntryUsage( gPalette, i, pmTolerant+pmExplicit, 0 );
  253.     }
  254.     c.red = c.green = c.blue = 65535;
  255.     SetEntryColor( gPalette, kPalWhite, &c );
  256.     
  257.     // • Force palette color entries into CTable.
  258.     
  259.     Palette2CTab( gPalette, gCTable );
  260. }
  261.     
  262. // • ------------------ Draw Contents of Frame PICT into GWorld ----------- 
  263.  
  264. static void
  265. DrawPICTToGWorld( const short frm )
  266. // •
  267. // • Draw the contents of an animation file into the GWorlds.
  268. {
  269.     GDHandle    currentDev = NullHandle;
  270.     CGrafPtr    currentPort = NullPointer;
  271.     
  272.     GetGWorld( ¤tPort, ¤tDev );    // • Save current port & device  
  273.         
  274.     if (gFramePICTs[ frm ] != NullHandle) {
  275.         HLock( (Handle) gFramePICTs[ frm ] );
  276.         LockPixels( GetGWorldPixMap( gFrames[ frm ] ) );                                    
  277.         SetGWorld( gFrames[ frm ], NullPointer );
  278.         DrawPicture( gFramePICTs[ frm ], &gBounds );
  279.         SetGWorld( currentPort, currentDev );    // • Reset port & device  
  280.         UnlockPixels( GetGWorldPixMap( gFrames[ frm ] ) );        
  281.         HUnlock( (Handle) gFramePICTs[ frm ] );
  282.     }                
  283. }
  284.  
  285. // • ------------------ Dispose of the Frame PICTs ------------------------ 
  286.     
  287. void
  288. DisposeFramePICTs( void )
  289. // •
  290. // • Dispose of the animation Picture records.
  291. {
  292.     short        i;
  293.     
  294.     for (i = 0; i < kMaxFrames; i++) {
  295.         if (gFramePICTs[ i ] != NullHandle) {             
  296.             KillPicture( gFramePICTs[ i ] );
  297.             gFramePICTs[ i ] = NullHandle;
  298.         }
  299.     }
  300. }
  301.  
  302.